import JSSM4 from "jssm4"; //主要使用
var key = "407D033B51C047CD";

/**
 * txt：要加密的字段
 *
 * @return {string}
 */
const sm3 = require("sm-crypto").sm3;
export function sm3Encrypt(txt) {
  let encryptData = sm3(txt); // 加密结果
  return encryptData;
}

/**
 * txt：要加密的字段
 * key:秘钥
 *
 * @return {string}
 */
const sm4 = require("sm-crypto").sm4;
export function encryptSM4(txt) {
  let encryptData = sm4.encrypt(txt, key); // 加密结果
  return encryptData;
}

// sm4解密
export function decryptedSM4(txt) {
  let encryptData = sm4.decrypt(txt, key); // 解密结果
  return encryptData;
}

//将json转为地址栏参数并且排序
function convertJsonToSortedQueryString(json) {
  // 步骤1：将JSON解析为JavaScript对象
  const jsonObj = JSON.parse(json);

  // 步骤2：按字母大小写排序属性
  const sortedKeys = Object.keys(jsonObj).sort();
  // 步骤3和步骤4：将排序后的属性和值转换为URL查询字符串格式
  let queryString = sortedKeys.map((key) => {
    const value = jsonObj[key];
    if (!value) {
      return;
    }
    // 使用encodeURIComponent对属性和值进行编码
    const encodedKey = encodeURIComponent(key);
    const encodedValue = value;
    return `${encodedKey}=${encodedValue}`;
  });
  // 步骤5：将所有查询字符串部分连接在一起
  queryString = queryString.filter((item) => {
    // 这个条件将保留非空的项
    return item !== undefined && item !== null && item !== "";
  });
  const sortedQueryString = queryString.join("&");
  return sortedQueryString;
}
export function getpublicData(params) {
  var timestamp = Date.now();
  let sort;
  if (params) {
    params = JSON.parse(decryptedSM4(params.parameter)); //传过来的是加密好的参数，所以在这解密转成对象
    params.timestamp = timestamp; //在排序之前手动添加时间戳参数
    params = JSON.stringify(params); //转之前必须为JSON字符串
    sort = convertJsonToSortedQueryString(params); //排序
    sort += "&key=HD7232D2AAAKA@978D8723H211?IER&6"; //在最后添加key
    return {
      sign: encryptSM4(sm3Encrypt(sort).toLocaleUpperCase()),
      timestamp: encryptSM4(timestamp.toString()),
      source: "ZRCSL7V0JIRK1PHY",
    };
  } else {
    params = params ? params : {};
    params.timestamp = timestamp;
    params = JSON.stringify(params);
    sort = convertJsonToSortedQueryString(params);
    sort += "&key=HD7232D2AAAKA@978D8723H211?IER&6"; //在最后添加key
    return {
      sign: encryptSM4(sm3Encrypt(sort).toLocaleUpperCase()),
      timestamp: encryptSM4(timestamp.toString()),
      source: "ZRCSL7V0JIRK1PHY",
    };
  }
}

// jssSM4加解密
// 加密
export function EncryptSM4(text) {
  if (!text || !key) return false;
  const sm4 = new JSSM4(key);
  let data = sm4.encryptData_ECB(text);
  return stringToHex(data);
}
// 解密
export function DecryptSM4(text) {
  if (!text || !key) return false;
  const sm4 = new JSSM4(key);
  text = hexToBase64(text);
  let data = JSON.parse(sm4.decryptData_ECB(text));
  return data;
}

//base64转16进制
function stringToHex(str) {
  const raw = atob(str);
  let result = "";
  for (let i = 0; i < raw.length; i++) {
    const hex = raw.charCodeAt(i).toString(16);
    result += hex.length === 2 ? hex : "0" + hex;
  }
  return result;
}
//16进制转base64
function hexToBase64(hex) {
  // 将16进制字符串转换为字节数组
  const bytes = [];
  for (let i = 0; i < hex.length; i += 2) {
    bytes.push(parseInt(hex.substr(i, 2), 16));
  }

  // 使用Uint8Array创建一个字节数组
  const byteArray = new Uint8Array(bytes);

  // 拆分byteArray为多个小数组
  let chunkSize = 100; // 根据实际情况调整拆分大小
  let chunks = [];
  for (let i = 0; i < byteArray.length; i += chunkSize) {
    let chunk = byteArray.slice(i, i + chunkSize);
    chunks.push(chunk);
  }

  // 逐个处理小数组并获取Base64编码结果
  let base64Results = chunks.map((chunk) =>
    String.fromCharCode.apply(null, chunk)
  );

  // 合并所有Base64编码结果
  let finalBase64 = base64Results.join("");
  // 使用btoa将字节数组转换为Base64字符串
  return btoa(finalBase64);
}

//封装请求头签名参数
export function headerOption(data) {
  if (!(data?.uId && data?.signToken)) {
    return null;
  }
  // 1.将timestamp+nonce+uId.toUpper()+signToken.toUpper()+key.toUpper()拼接后字符升序排列。
  // 2.使用sm3生成对应摘要内容。
  let timestamp = new Date().getTime().toString(); //时间戳
  let nonce = Math.floor(100000 + Math.random() * 900000).toString(); //随机6位数
  let uid = data.uId;
  let signToken = data.signToken;
  let signature =
    timestamp +
    nonce +
    uid.toUpperCase() +
    signToken.toUpperCase() +
    key.toUpperCase(); //按照要求拼接
  signature = signature.split("").sort().join(""); //对字符串进行排序
  return {
    signature: EncryptSM4(sm3Encrypt(signature)),
    uid: EncryptSM4(uid),
    nonce: EncryptSM4(nonce),
    timestamp: EncryptSM4(timestamp),
  };
}
